#include "usart.h"
#include "usbd_def.h"
#include "usbd_cdc.h"
#include "usbd_conf.h"
//#include "stdio.h"


#pragma  diag_suppress 870

u8  STM2PC_Data_BUF[1024];	
u16 crc16_data = 0;
u8  Working_Mode = Normal_Mode;

//////////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数               
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;       
//定义_sys_exit()以避免使用 半主机模式
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数
int fputc(int ch, FILE *f)
{ 	
	while((USART1->ISR&0X40)==0);//Ñ­»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï   
	USART1->TDR=(u8)ch;      
	return ch;
}
#endif


u16 crc16(u8 *addr, u16 num, u16 crc)
{
    u16 i;
	u16 x;
    for(x=0; x<num; x++)             
    {
        crc = crc ^ (addr[x] << 8);     /* Fetch byte from memory, XOR into CRC top byte*/
        for (i = 0; i < 8; i++)             /* Prepare to rotate 8 bits */
        {
            if (crc & 0x8000)            /* b15 is set... */
                crc = (crc << 1) ^ 0x1021;    /* rotate and XOR with polynomic */
            else                          /* b15 is clear... */
                crc <<= 1;                  /* just rotate */
        }                             /* Loop for 8 bits */
//        crc &= 0xFFFF;                  /* Ensure CRC remains 16-bit value */
    }                               /* Loop until num=0 */
    return(crc);                    /* Return updated CRC */
}


//#if EN_USART1_RX   //
//
//  	
u8 USART_RX_BUF[USART_REC_LEN];     //

u16 USART_RX_STA=0;       //	

u8 aRxBuffer[RXBUFFERSIZE];//
UART_HandleTypeDef UART1_Handler; //

//  
//bound:

void uart1_init(u32 bound)
{	
	//UART 
	UART1_Handler.Instance=USART1;					    //
	UART1_Handler.Init.BaudRate=bound;				    //
	UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //
	UART1_Handler.Init.StopBits=UART_STOPBITS_1;	    //
	UART1_Handler.Init.Parity=UART_PARITY_NONE;		    //
	UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //
	UART1_Handler.Init.Mode=UART_MODE_TX_RX;		    //
	HAL_UART_Init(&UART1_Handler);					    //HAL_UART_Init()
	
	//HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//
  
}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
	GPIO_InitTypeDef GPIO_Initure;	
	if(huart->Instance==USART1)// 
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			//
		__HAL_RCC_USART1_CLK_ENABLE();			//
	
		GPIO_Initure.Pin=GPIO_PIN_9;			//PA9
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//
		GPIO_Initure.Pull=GPIO_PULLUP;			//
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	//
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//

		GPIO_Initure.Pin=GPIO_PIN_10;			//PA10
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//
		
#if EN_USART1_RX
		HAL_NVIC_EnableIRQ(USART1_IRQn);				//
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);			//
#endif	
	}

}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)//
	{
		if((USART_RX_STA&0x8000)==0)//
		{
			if(USART_RX_STA&0x4000)//
			{
				if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//,
				else USART_RX_STA|=0x8000;	// 
			}
			else //
			{	
				if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//,	  
				}		 
			}
		}
	}
}
 
//
void USART1_IRQHandler(void)                	
{ 
	u32 timeout=0;
    u32 maxDelay=0x1FFFF;	
	HAL_UART_IRQHandler(&UART1_Handler);	//	
	timeout=0;
    while (HAL_UART_GetState(&UART1_Handler)!=HAL_UART_STATE_READY)//
	{
        timeout++;////
        if(timeout>maxDelay) break;		
	}  
	timeout=0;
	while(HAL_UART_Receive_IT(&UART1_Handler,(u8 *)aRxBuffer, RXBUFFERSIZE)!=HAL_OK)//
	{
        timeout++; //
        if(timeout>maxDelay) break;	
	}
} 

void STM2PC_ERROR(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 State,u8 CMD,u8 ERROR_CODE,u8 Other_data)
{
//	u8 i=0;
	STM2PC_Data_BUF[0]=State;
    STM2PC_Data_BUF[1]=CMD;	   	
	STM2PC_Data_BUF[2]=0x15;			
	STM2PC_Data_BUF[3]=ERROR_CODE;  	
	STM2PC_Data_BUF[4]=Other_data;		
	STM2PC_Data_BUF[5]=0X00;	
	STM2PC_Data_BUF[6]=0X00;		
	STM2PC_Data_BUF[7]=0X00;	
	STM2PC_Data_BUF[8]=0X00;	
	STM2PC_Data_BUF[9]=0X00;	
	STM2PC_Data_BUF[10]=0X00;		
	STM2PC_Data_BUF[11]=0X00;		
	STM2PC_Data_BUF[12]=0X00;	  	
	STM2PC_Data_BUF[13]=0X00;		
	STM2PC_Data_BUF[14]=0X00;		
	STM2PC_Data_BUF[15]=0x00;
	STM2PC_Data_BUF[16]=0x00;
	STM2PC_Data_BUF[17]=0x00;
	STM2PC_Data_BUF[18]=0x00;
	STM2PC_Data_BUF[19]=0x00;
	STM2PC_Data_BUF[20]=0x00;
	STM2PC_Data_BUF[21]=0x00;
	STM2PC_Data_BUF[22]=0x00;
	crc16_data = crc16(STM2PC_Data_BUF, 23, 0xFFFF);	
	STM2PC_Data_BUF[23]=(u8)(crc16_data>>8);			
	STM2PC_Data_BUF[24]=(u8)(crc16_data&0x00ff);

    USBD_LL_Transmit(pdev,CDC_IN_EP,STM2PC_Data_BUF,25); 
    	
}

void STM2PC_RM671xx(USBD_HandleTypeDef *pdev,uint8_t  ep_addr, u8 table[],u8 length)
{
	u8 i=0;
    for(i=0;i<length;i++)
    {
        STM2PC_Data_BUF[i] = table[i];
    }
	crc16_data = crc16(STM2PC_Data_BUF, length, 0xFFFF);	
	STM2PC_Data_BUF[length]=(u8)(crc16_data>>8);			
	STM2PC_Data_BUF[length+1]=(u8)(crc16_data&0x00ff);

    USBD_LL_Transmit(pdev,CDC_IN_EP,STM2PC_Data_BUF,length+2);    	
}

void STM2PC_LCDConfig(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 CMD,u8 table[],u8 ERROR_CODE)
{
//	u8 i=0;
	STM2PC_Data_BUF[0]=0X0A;
    STM2PC_Data_BUF[1]=CMD;	   	
	STM2PC_Data_BUF[2]=0x15;	
	STM2PC_Data_BUF[3]=ERROR_CODE;	
	STM2PC_Data_BUF[4]=table[33];  	
	STM2PC_Data_BUF[5]=table[32];			//HP = 33<<8 + 32
	STM2PC_Data_BUF[6]=table[40];			//HF
	STM2PC_Data_BUF[7]=table[36];			//HB
	STM2PC_Data_BUF[8]=table[44];			//HS
	STM2PC_Data_BUF[9]=table[35];			
	STM2PC_Data_BUF[10]=table[34];			//VP = 35<<8 + 34
	STM2PC_Data_BUF[11]=table[42];			//VF
	STM2PC_Data_BUF[12]=table[38];			//VB
	STM2PC_Data_BUF[13]=table[46];	  	//VS
	STM2PC_Data_BUF[14]=table[50];			//50<<8 + 49  == 像素时钟  	
	STM2PC_Data_BUF[15]=table[49];		
	STM2PC_Data_BUF[16]=table[48];			//S_D_6_8 RGB/MIPI/DP
	STM2PC_Data_BUF[17]=table[56];			//LCDConfig
	STM2PC_Data_BUF[18]=table[63];			//RGB:0X55,MIPI:0XA1,0XA2,0XA3
	STM2PC_Data_BUF[19]=0x00;
	STM2PC_Data_BUF[20]=0x00;
	STM2PC_Data_BUF[21]=0x00;
	STM2PC_Data_BUF[22]=0x00;
	
	crc16_data = crc16(STM2PC_Data_BUF, 23, 0xFFFF);	
	STM2PC_Data_BUF[23]=(u8)(crc16_data>>8);			
	STM2PC_Data_BUF[24]=(u8)(crc16_data&0x00ff);

    USBD_LL_Transmit(pdev,CDC_IN_EP,STM2PC_Data_BUF,25); 	
}


void STM2PC_Pattern(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 CMD,u8 R,u8 G,u8 B,u8 ERROR_CODE)
{
//	u8 i=0;
	STM2PC_Data_BUF[0]=0X0A;
    STM2PC_Data_BUF[1]=CMD;	   	
	STM2PC_Data_BUF[2]=0x15;	
	STM2PC_Data_BUF[3]=ERROR_CODE;	
	STM2PC_Data_BUF[4]=R;  	
	STM2PC_Data_BUF[5]=G;	
	STM2PC_Data_BUF[6]=B;		
	STM2PC_Data_BUF[7]=0X00;	
	STM2PC_Data_BUF[8]=0X00;	
	STM2PC_Data_BUF[9]=0X00;	
	STM2PC_Data_BUF[10]=0X00;		
	STM2PC_Data_BUF[11]=0X00;		
	STM2PC_Data_BUF[12]=0X00;	  	
	STM2PC_Data_BUF[13]=0X00;		
	STM2PC_Data_BUF[14]=0X00;		
	STM2PC_Data_BUF[15]=0x00;
	STM2PC_Data_BUF[16]=0x00;
	STM2PC_Data_BUF[17]=0x00;
	STM2PC_Data_BUF[18]=0x00;
	STM2PC_Data_BUF[19]=0x00;
	STM2PC_Data_BUF[20]=0x00;
	STM2PC_Data_BUF[21]=0x00;
	STM2PC_Data_BUF[22]=0x00;
	
	crc16_data = crc16(STM2PC_Data_BUF, 23, 0xFFFF);	
	STM2PC_Data_BUF[23]=(u8)(crc16_data>>8);			
	STM2PC_Data_BUF[24]=(u8)(crc16_data&0x00ff);

    USBD_LL_Transmit(pdev,CDC_IN_EP,STM2PC_Data_BUF,25); 	
}


void STM2PC_SW_Version(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 State,u8 CMD,u8 ERROR_CODE,u8 Version,u8 SubVersion,u8 ID)
{
	STM2PC_Data_BUF[0]=State;
  STM2PC_Data_BUF[1]=CMD;	   	
	STM2PC_Data_BUF[2]=0x15;			
	STM2PC_Data_BUF[3]=ERROR_CODE;  	
	STM2PC_Data_BUF[4]=Version;		
	STM2PC_Data_BUF[5]=SubVersion;	
	STM2PC_Data_BUF[6]=ID;		
	STM2PC_Data_BUF[7]=0X00;	
	STM2PC_Data_BUF[8]=0X00;	
	STM2PC_Data_BUF[9]=0X00;	
	STM2PC_Data_BUF[10]=0X00;		
	STM2PC_Data_BUF[11]=0X00;		
	STM2PC_Data_BUF[12]=0X00;	  	
	STM2PC_Data_BUF[13]=0X00;		
	STM2PC_Data_BUF[14]=0X00;		
	STM2PC_Data_BUF[15]=0x00;
	STM2PC_Data_BUF[16]=0x00;
	STM2PC_Data_BUF[17]=0x00;
	STM2PC_Data_BUF[18]=0x00;
	STM2PC_Data_BUF[19]=0x00;
	STM2PC_Data_BUF[20]=0x00;
	STM2PC_Data_BUF[21]=0x00;
	STM2PC_Data_BUF[22]=0x00;
	crc16_data = crc16(STM2PC_Data_BUF, 23, 0xFFFF);	
	STM2PC_Data_BUF[23]=(u8)(crc16_data>>8);			
	STM2PC_Data_BUF[24]=(u8)(crc16_data&0x00ff);

    USBD_LL_Transmit(pdev,CDC_IN_EP,STM2PC_Data_BUF,25);	
}

void STM2PC_FilConfig(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 State,u8 CMD,u8 table[],u16 num ,u8 ERROR_CODE)
{
		u16 i=0;
		STM2PC_Data_BUF[0]=State;
		STM2PC_Data_BUF[1]=CMD;	   	
		STM2PC_Data_BUF[2]=(u8)(num>>8);
		STM2PC_Data_BUF[3]=(u8)num;		
		STM2PC_Data_BUF[4]=ERROR_CODE;

		if(CMD == 0x01)
		{
				for(i=0;i<num;i++)
				STM2PC_Data_BUF[i+5]=table[i];  
		}		
		crc16_data = crc16(STM2PC_Data_BUF, num+5, 0xFFFF);	
		STM2PC_Data_BUF[num+5]=(u8)(crc16_data>>8);			
		STM2PC_Data_BUF[num+6]=(u8)(crc16_data&0x00ff);

		USBD_LL_Transmit(pdev,CDC_IN_EP,STM2PC_Data_BUF,num+7);	
}

void Mode_Display(void)
{
	if(Working_Mode == Normal_Mode)
	{
			//printf(" 当前工作模式为Normal_Mode\r\n");
			delay_ms(7);
		//printf(" \r\n");
	}
			
	else
	{
			//printf(" 当前工作模式为 Debug_Mode\r\n");
			delay_ms(7);
		//printf(" \r\n");
	}
}



